/*!
 * \file ParserAdapter.cpp
 * \project	WonderTrader
 *
 * \author Wesley
 * \date 2020/03/30
 * 
 * \brief 行情解析器适配器实现文件
 * 
 * \details 行情解析器适配器的具体实现，提供统一的行情数据接口和管理功能。
 *          实现了多种行情数据类型的接收、过滤、转换和分发机制。
 */
#include "ParserAdapter.h"
#include "WtUftEngine.h"
#include "WtHelper.h"

#include "../Includes/WTSContractInfo.hpp"
#include "../Includes/WTSDataDef.hpp"
#include "../Includes/WTSVariant.hpp"
#include "../Includes/IBaseDataMgr.h"

#include "../Share/StrUtil.hpp"

#include "../WTSTools/WTSLogger.h"

USING_NS_WTP;

//////////////////////////////////////////////////////////////////////////
//ParserAdapter
ParserAdapter::ParserAdapter()
	: _parser_api(NULL)
	, _remover(NULL)
	, _stopped(false)
	, _bd_mgr(NULL)
	, _stub(NULL)
	, _cfg(NULL)
{
	//! 构造函数实现 - 初始化所有成员变量为NULL或默认值
	//! 采用安全的初始化方式，确保对象处于可控状态
}


ParserAdapter::~ParserAdapter()
{
	//! 析构函数实现 - 资源清理由release()方法负责
	//! 确保在对象销毁时不会出现资源泄漏
}

bool ParserAdapter::init(const char* id, WTSVariant* cfg, IParserStub* stub, IBaseDataMgr* bgMgr)
{
	/*!
	 * \brief 初始化行情适配器的核心实现
	 * 
	 * \details 完整的初始化流程包括：
	 *          1. 参数验证和基本设置
	 *          2. 动态加载解析器模块
	 *          3. 创建解析器API实例
	 *          4. 配置数据过滤器
	 *          5. 订阅合约数据
	 *          
	 * \note 此方法负责从配置中加载解析器模块，是最常用的初始化方式
	 */
	if (cfg == NULL)
		return false;

	_stub = stub;
	_bd_mgr = bgMgr;
	_id = id;

	if (_cfg != NULL)
		return false;

	_cfg = cfg;
	_cfg->retain();

	{
		// 加载解析器模块
		if (cfg->getString("module").empty())
			return false;

		std::string module = DLLHelper::wrap_module(cfg->getCString("module"), "lib");;

		// 先从插件目录查找是否有解析模块
		std::string dllpath = WtHelper::getModulePath(module.c_str(), "parsers", true);
		// 如果没有,再从模块目录,即dll同目录找
		if (!StdFile::exists(dllpath.c_str()))
			dllpath = WtHelper::getModulePath(module.c_str(), "parsers", false);

		DllHandle hInst = DLLHelper::load_library(dllpath.c_str());
		if (hInst == NULL)
		{
			WTSLogger::log_dyn("parser", _id.c_str(), LL_ERROR, "[%s] Parser module %s loading failed", _id.c_str(), dllpath.c_str());
			return false;
		}
		else
		{
			WTSLogger::log_dyn("parser", _id.c_str(), LL_INFO, "[%s] Parser module %s loaded", _id.c_str(), dllpath.c_str());
		}

		FuncCreateParser pFuncCreateParser = (FuncCreateParser)DLLHelper::get_symbol(hInst, "createParser");
		if (NULL == pFuncCreateParser)
		{
			WTSLogger::log_dyn("parser", _id.c_str(), LL_FATAL, "[%s] Entrance function createParser not found", _id.c_str());
			return false;
		}

		_parser_api = pFuncCreateParser();
		if (NULL == _parser_api)
		{
			WTSLogger::log_dyn("parser", _id.c_str(), LL_FATAL, "[%s] Creating parser api failed", _id.c_str());
			return false;
		}

		_remover = (FuncDeleteParser)DLLHelper::get_symbol(hInst, "deleteParser");
	}
	
	// 配置交易所过滤器
	const std::string& strFilter = cfg->getString("filter");
	if (!strFilter.empty())
	{
		const StringVector &ayFilter = StrUtil::split(strFilter, ",");
		auto it = ayFilter.begin();
		for (; it != ayFilter.end(); it++)
		{
			_exchg_filter.insert(*it);
		}
	}

	// 配置合约代码过滤器
	std::string strCodes = cfg->getString("code");
	if (!strCodes.empty())
	{
		const StringVector &ayCodes = StrUtil::split(strCodes, ",");
		auto it = ayCodes.begin();
		for (; it != ayCodes.end(); it++)
		{
			_code_filter.insert(*it);
		}
	}

	if (_parser_api)
	{
		_parser_api->registerSpi(this);

		if (_parser_api->init(cfg))
		{
			ContractSet contractSet;
			WTSArray* ay = _bd_mgr->getContracts();
			for(auto it = ay->begin(); it != ay->end(); it++)
			{
				WTSContractInfo* cInfo = STATIC_CONVERT(*it, WTSContractInfo*);

				// 先检查合约品种代码是否需要过滤
				if(!_code_filter.empty())
				{
					auto cit = _code_filter.find(cInfo->getFullCode());
					auto pit = _code_filter.find(cInfo->getFullPid());
					if (cit != _code_filter.end() || pit != _code_filter.end())
					{
						contractSet.insert(cInfo->getFullCode());
						continue;
					}
				}
				
				// 再检查交易所是否需要过滤
				if (!_exchg_filter.empty())
				{
					auto eit = _exchg_filter.find(cInfo->getExchg());
					if (eit != _code_filter.end())
					{
						contractSet.insert(cInfo->getFullCode());
						continue;
					}
					else
					{
						continue;
					}
				}

				// 如果没有设置任何过滤器，则订阅所有合约
				if(_code_filter.empty() && _exchg_filter.empty())
					contractSet.insert(cInfo->getFullCode());

			}
			ay->release();

			_parser_api->subscribe(contractSet);
			contractSet.clear();
		}
		else
		{
			WTSLogger::log_dyn("parser", _id.c_str(), LL_ERROR, "[%s] Parser initializing failed: api initializing failed...", _id.c_str());
		}
	}
	else
	{
		WTSLogger::log_dyn("parser", _id.c_str(), LL_ERROR, "[%s] Parser initializing failed: creating api failed...", _id.c_str());
	}

	return true;
}

bool ParserAdapter::initExt(const char* id, IParserApi* api, IParserStub* stub, IBaseDataMgr* bgMgr)
{
	/*!
	 * \brief 扩展初始化方法的实现
	 * 
	 * \details 使用外部提供的解析器API进行初始化，适用于已有API实例的场景。
	 *          与标准初始化方法的区别是不需要加载模块，直接使用提供的API实例。
	 *          同样会进行合约订阅，但不进行过滤器配置。
	 */
	if (api == NULL)
		return false;

	_parser_api = api;
	_stub = stub;
	_bd_mgr = bgMgr;
	_id = id;

	if (_parser_api)
	{
		_parser_api->registerSpi(this);

		if (_parser_api->init(NULL))
		{
			ContractSet contractSet;
			WTSArray* ay = _bd_mgr->getContracts();
			for (auto it = ay->begin(); it != ay->end(); it++)
			{
				WTSContractInfo* cInfo = STATIC_CONVERT(*it, WTSContractInfo*);

				// 先检查合约品种代码是否需要过滤
				if (!_code_filter.empty())
				{
					auto cit = _code_filter.find(cInfo->getFullCode());
					auto pit = _code_filter.find(cInfo->getFullPid());
					if (cit != _code_filter.end() || pit != _code_filter.end())
					{
						contractSet.insert(cInfo->getFullCode());
						continue;
					}
				}

				// 再检查交易所是否需要过滤
				if (!_exchg_filter.empty())
				{
					auto eit = _exchg_filter.find(cInfo->getExchg());
					if (eit != _code_filter.end())
					{
						contractSet.insert(cInfo->getFullCode());
						continue;
					}
					else
					{
						continue;
					}
				}

				// 如果没有设置任何过滤器，则订阅所有合约
				if (_code_filter.empty() && _exchg_filter.empty())
					contractSet.insert(cInfo->getFullCode());

			}
			ay->release();

			_parser_api->subscribe(contractSet);
			contractSet.clear();
		}
		else
		{
			WTSLogger::log_dyn("parser", _id.c_str(), LL_ERROR, "[%s] Parser initializing failed: api initializing failed...", _id.c_str());
		}
	}

	return true;
}

void ParserAdapter::release()
{
	/*!
	 * \brief 释放适配器资源的实现
	 * 
	 * \details 完整的资源释放流程：
	 *          1. 设置停止标志，阻止新的数据处理
	 *          2. 释放解析器API资源
	 *          3. 使用正确的删除函数清理API对象
	 *          
	 * \note 优先使用模块提供的删除函数，如果没有则使用delete操作符
	 */
	_stopped = true;
	if (_parser_api)
	{
		_parser_api->release();
	}

	if (_remover)
		_remover(_parser_api);
	else
		delete _parser_api;
}

bool ParserAdapter::run()
{
	/*!
	 * \brief 启动适配器的实现
	 * 
	 * \details 启动行情数据接收，调用解析器API的连接方法开始数据流处理
	 */
	if (_parser_api == NULL)
		return false;

	_parser_api->connect();
	return true;
}

void ParserAdapter::handleQuote(WTSTickData *quote, uint32_t procFlag)
{
	/*!
	 * \brief 处理实时行情数据的核心实现
	 * 
	 * \details 行情数据处理流程：
	 *          1. 数据有效性验证（NULL检查、停止状态检查、日期检查）
	 *          2. 合约信息获取和验证
	 *          3. 设置标准化的合约代码
	 *          4. 转发给数据处理桩
	 *          
	 * \note 这是最重要的数据处理方法，确保数据的完整性和正确性
	 */
	if (quote == NULL || _stopped || quote->actiondate() == 0 || quote->tradingdate() == 0)
		return;

	WTSContractInfo* cInfo = quote->getContractInfo();
	if (cInfo == NULL) cInfo = _bd_mgr->getContract(quote->code(), quote->exchg());
	if (cInfo == NULL)
		return;

	quote->setCode(cInfo->getFullCode());

	_stub->handle_push_quote(quote);
}

void ParserAdapter::handleOrderQueue(WTSOrdQueData* ordQueData)
{
	/*!
	 * \brief 处理委托队列数据的实现
	 * 
	 * \details Level2委托队列数据处理流程：
	 *          1. 停止状态和交易所过滤检查
	 *          2. 数据有效性验证（日期检查）
	 *          3. 合约信息获取和验证
	 *          4. 设置标准化的合约代码
	 *          5. 转发给数据处理桩
	 */
	if (_stopped)
		return;

	if (!_exchg_filter.empty() && (_exchg_filter.find(ordQueData->exchg()) == _exchg_filter.end()))
		return;

	if (ordQueData->actiondate() == 0 || ordQueData->tradingdate() == 0)
		return;

	WTSContractInfo* cInfo = _bd_mgr->getContract(ordQueData->code(), ordQueData->exchg());
	if (cInfo == NULL)
		return;

	ordQueData->setCode(cInfo->getFullCode());

	if (_stub)
		_stub->handle_push_order_queue(ordQueData);
}

void ParserAdapter::handleOrderDetail(WTSOrdDtlData* ordDtlData)
{
	/*!
	 * \brief 处理委托明细数据的实现
	 * 
	 * \details Level2委托明细数据处理流程：
	 *          1. 停止状态和交易所过滤检查
	 *          2. 数据有效性验证（日期检查）
	 *          3. 合约信息获取和验证
	 *          4. 设置标准化的合约代码
	 *          5. 转发给数据处理桩
	 */
	if (_stopped)
		return;

	if (!_exchg_filter.empty() && (_exchg_filter.find(ordDtlData->exchg()) == _exchg_filter.end()))
		return;

	if (ordDtlData->actiondate() == 0 || ordDtlData->tradingdate() == 0)
		return;

	WTSContractInfo* cInfo = _bd_mgr->getContract(ordDtlData->code(), ordDtlData->exchg());
	if (cInfo == NULL)
		return;

	ordDtlData->setCode(cInfo->getFullCode());

	if (_stub)
		_stub->handle_push_order_detail(ordDtlData);
}

void ParserAdapter::handleTransaction(WTSTransData* transData)
{
	/*!
	 * \brief 处理成交明细数据的实现
	 * 
	 * \details Level2成交明细数据处理流程：
	 *          1. 停止状态和交易所过滤检查
	 *          2. 数据有效性验证（日期检查）
	 *          3. 合约信息获取和验证
	 *          4. 设置标准化的合约代码
	 *          5. 转发给数据处理桩
	 */
	if (_stopped)
		return;

	if (!_exchg_filter.empty() && (_exchg_filter.find(transData->exchg()) == _exchg_filter.end()))
		return;

	if (transData->actiondate() == 0 || transData->tradingdate() == 0)
		return;

	WTSContractInfo* cInfo = _bd_mgr->getContract(transData->code(), transData->exchg());
	if (cInfo == NULL)
		return;

	transData->setCode(cInfo->getFullCode());

	if (_stub)
		_stub->handle_push_transaction(transData);
}


void ParserAdapter::handleParserLog(WTSLogLevel ll, const char* message)
{
	/*!
	 * \brief 处理解析器日志的实现
	 * 
	 * \details 将来自解析器API的日志消息转发到系统日志模块，
	 *          用于监控和调试解析器的运行状态
	 */
	if (_stopped)
		return;

	WTSLogger::log_dyn_raw("parser", _id.c_str(), ll, message);
}


//////////////////////////////////////////////////////////////////////////
//ParserAdapterMgr
void ParserAdapterMgr::release()
{
	/*!
	 * \brief 释放管理器资源的实现
	 * 
	 * \details 遍历所有管理的适配器，逐一调用release方法释放资源，
	 *          然后清空适配器映射表
	 */
	for (auto it = _adapters.begin(); it != _adapters.end(); it++)
	{
		it->second->release();
	}

	_adapters.clear();
}

bool ParserAdapterMgr::addAdapter(const char* id, ParserAdapterPtr& adapter)
{
	/*!
	 * \brief 添加适配器的实现
	 * 
	 * \details 添加新的适配器到管理器中：
	 *          1. 参数有效性验证
	 *          2. ID重复性检查
	 *          3. 添加到映射表中
	 *          
	 * \return 添加成功返回true，失败返回false
	 */
	if (adapter == NULL || strlen(id) == 0)
		return false;

	auto it = _adapters.find(id);
	if (it != _adapters.end())
	{
		WTSLogger::error(" Same name of parsers: %s", id);
		return false;
	}

	_adapters[id] = adapter;

	return true;
}


ParserAdapterPtr ParserAdapterMgr::getAdapter(const char* id)
{
	/*!
	 * \brief 获取指定适配器的实现
	 * 
	 * \details 根据ID在映射表中查找对应的适配器实例
	 * 
	 * \return 找到返回适配器智能指针，未找到返回空指针
	 */
	auto it = _adapters.find(id);
	if (it != _adapters.end())
	{
		return it->second;
	}

	return ParserAdapterPtr();
}

void ParserAdapterMgr::run()
{
	/*!
	 * \brief 启动所有适配器的实现
	 * 
	 * \details 遍历所有管理的适配器，逐一调用run方法启动数据接收，
	 *          并记录启动的适配器数量
	 */
	for (auto it = _adapters.begin(); it != _adapters.end(); it++)
	{
		it->second->run();
	}

	WTSLogger::info("%u parsers started", _adapters.size());
}